library(leaflet)
library(tidyverse)
leaflet() %>%
# Mitte auf München setzen
setView(lng = 11.572347, lat = 48.138345, zoom = 12) %>%
# Hintergrundkarte festlegen
addProviderTiles(providers$OpenStreetMap.DE, group = "Open Street Map DE") %>%
# Zusätzliche Hintergrundkarten als Alternative
addProviderTiles(providers$Esri.WorldImagery, group = "ESRI World Imagery") %>%
# Auswahlfeld für den Nutzer um sich für eine Hintergrundkarte zu entscheiden
addLayersControl(
baseGroups = c("Open Street Map DE","ESRI World Imagery") )R Leaflet
Leaflet ist eine Open Source Bibliothek mit der interaktive Karten erstellt werden können. Über das R-Package leaflet lassen sich verschiedene GIS-Daten (z.B. Koordinaten, Layer) in interaktiven Karten darstellen.
Einfache Karte
Um eine einfache LeafletKarte zu erstellen, benötigen wir eine Hintergrundkarte und einen Kartenausschnitt, der dargestellt werden soll. Die Region kann entweder über eine Koordinate herangezoomt werden, oder durch hinzufügen eines Layers (z.B. aus einer Shape-Datei). Es gibt eine Vielzahl an möglichen Hintergrunddaten. Eine sehr umfangreiche Übersicht an Hintergrundkarten findet man z.B. hier: Kartenauswahl
Karte mit Suchfunktion
Um Adressen suchen zu können, lässt sich mit dem package leaflet.extras ein Suchfenster einbinden (addSearchOSM()). Mit addReverseSearchOSM() lassen sich per Mouseklick die Adresse und die Geokoordinaten der angeklickten Stelle anzeigen. Mit addResetMapButton() wird ein Button integriert, mit dem man wieder in den ursprünglichen Kartenausschnitt zurückspringen kann.
library(leaflet.extras)
leaflet() %>%
# Mitte auf München setzen
setView(lng = 11.572347, lat = 48.138345, zoom = 12) %>%
# Hintergrundkarte festlegen
addProviderTiles(providers$OpenStreetMap.DE, group = "Open Street Map DE") %>%
addSearchOSM() %>%
addReverseSearchOSM(showBounds = T, showSearchLocation = F) %>%
addResetMapButton()
Marker einfügen
Um Marker einzeichnet zu können, simulieren wir für Deutschland, Österreich und die Schweiz Koordinaten. Diese werden drei Kategorien zugeordnet, nach denen sie später eingefärbt werden können. Im Package rnaturalearth sind die Geometrien der Länder verfügbar.
library(rnaturalearth)
library(sf)
deu = ne_countries(country = "Germany", scale = "medium", returnclass = "sf") %>%
# Transformation nach WGS84 (entspricht crs 4326)
st_transform(crs = 4326)
oe = ne_countries(country = "Austria", scale = "medium", returnclass = "sf") %>%
# Transformation nach WGS84 (entspricht crs 4326)
st_transform(crs = 4326)
ch = ne_countries(country = "Switzerland", scale = "medium", returnclass = "sf") %>%
# Transformation nach WGS84 (entspricht crs 4326)
st_transform(crs = 4326)
#Koordinaten simulieren
set.seed(1234)
deutschand_punkte = st_sample(deu, size = 150)
oesterreich_punkte = st_sample(oe, size = 50)
schweiz_punkte = st_sample(ch, size = 50)
# Zu einem Datensatz zusammenfassen
#Deutschland
deutschand_punkte_df <- as.data.frame(st_coordinates(deutschand_punkte))
deutschand_punkte_df <- cbind(deutschand_punkte_df, Typ = sample(c("A", "B", "C"), size = nrow(deutschand_punkte_df), replace = T, prob = c(0.2, 0.3, 0.5))) %>%
mutate(Land = "Deutschland")
# Österreich
oesterreich_punkte_df <- as.data.frame(st_coordinates(oesterreich_punkte))
oesterreich_punkte_df <- cbind(oesterreich_punkte_df, Typ = sample(c("A", "B", "C"), size = nrow(oesterreich_punkte_df), replace = T, prob = c(0.4, 0.1, 0.5))) %>%
mutate(Land = "Österreich")
# Schweiz
schweiz_punkte_df <- as.data.frame(st_coordinates(schweiz_punkte))
schweiz_punkte_df <- cbind(schweiz_punkte_df, Typ = sample(c("A", "B", "C"), size = nrow(schweiz_punkte_df), replace = T, prob = c(0.6, 0.2, 0.2))) %>%
mutate(Land = "Schweiz")
dach_df <- rbind(deutschand_punkte_df, oesterreich_punkte_df, schweiz_punkte_df)Im Dataframe dach_df sind nun für die Länder Deutschand, Österreich und Schweiz die Koordinaten vorhanden.
leaflet(data = dach_df) %>%
addTiles() %>% # Default ist hier OpenStreetMap
addMarkers(~X, ~Y, popup = ~as.character(Typ), label = ~as.character(Typ))
Cluster
Besonders wenn es sich um viele Marker bei niedriger Zoomstufe handelt, ist die Darstellung der einzelnen Icons manchmal unübersichtlich. Teilweise gibt es auch Darstellungsprobleme wenn mehrere Marker mit der gleichen Koordinate hinterlegt sind. In solchen Fällen bietet sich eine Clusterdarstellung an.
leaflet(data = dach_df) %>%
addTiles() %>%
addMarkers(~X,
~Y,
popup = ~as.character(Typ),
label = ~as.character(Typ),
clusterOptions = markerClusterOptions())
Individuelle Icons
Sollen die drei verschiedenen Typen klarer voneinander unterscheidbar sein, so kann das über individuell gestaltete Icons erfolgen. Mit AwesomeIcons steht eine Vielzahl an Icons zur Verfügung. Eine Übersicht der Icons findet sich hier: fontawesome.
Wir nehmen an dass es sich bei den Typen A - C um verschiedenen Fahrzeugtypen handelt. Mögliche Icons könnten also so gestaltet werden:
# Icons für die verschiedenen Typen definieren
IconSet <- awesomeIconList(
"A" = makeAwesomeIcon(icon = 'car', markerColor = 'blue', iconColor = 'black', library = "fa"),
"B" = makeAwesomeIcon(icon = 'truck', markerColor = 'orange', iconColor = 'black', library = "fa"),
"C" = makeAwesomeIcon(icon = 'motorcycle', markerColor = 'green', iconColor = 'black', library = "fa")
)
# Punktlayer erstellen
dach_df_punktlayer <- sp::SpatialPointsDataFrame(as.matrix(dach_df[,c("X","Y")]), dach_df[,c("Typ","Land")])
# Karte erstellen
leaflet(data = dach_df_punktlayer) %>%
addTiles() %>%
addAwesomeMarkers(icon = ~IconSet[Typ], label = ~paste("Fahrzeugtyp ",as.character(Typ)))
Minicharts
mit dem Package leaflet.minicharts lassen sich Verteilungen auf die Landkarte plotten. Dazu benötigen wir geeignete Daten zu den Ländern. In diesem Fall wird die Anzahl der Typen A - C je Land gezäht.
# Daten aus Koordinaten aggregieren:
dach_df_agg <- dach_df %>%
group_by(Typ,Land) %>%
summarize(Anz = n_distinct(X)) %>%
pivot_wider(names_from = Typ,values_from = Anz) %>%
ungroup()
dach_agg_ges = dach_df %>%
group_by(Land) %>%
summarize(X = mean(X), Y = mean(Y)) %>%
ungroup() %>%
left_join(dach_df_agg, by = "Land")Diese Daten lassen sich nun als Balkendiagramme auf die einzelnen Länder legen.
library(leaflet.minicharts)
leaflet(data = dach_agg_ges) %>%
addProviderTiles(providers$Esri.WorldGrayCanvas) %>% # Default ist hier OpenStreetMap
addMinicharts(lng = dach_agg_ges$X, lat = dach_agg_ges$Y, type = "bar", chartdata = dach_agg_ges[,4:6], width =80, height = 80)